#ifndef UnstructMG_GMRES_HPP
#define UnstructMG_GMRES_HPP

#include "iter_solver.hpp"

template<typename idx_t, typename pc_data_t, typename pc_calc_t, typename ksp_t, int dof>
class GMRESSolver : public IterativeSolver<idx_t, pc_data_t, pc_calc_t, ksp_t, dof> {
public:
    GMRESSolver();
    void SetRestartlen(int rstl);
protected:
    int restart_len = 10;
    void Mult_ipl(const par_Vector<idx_t, ksp_t, dof> & b, par_Vector<idx_t, ksp_t, dof> & x) const ;
};

typedef GMRESSolver<int, double, double, double, 1> GMRESSolver_I32All64_DOF1;
typedef GMRESSolver<int, double, double, double, 2> GMRESSolver_I32All64_DOF2;
typedef GMRESSolver<int, double, double, double, 3> GMRESSolver_I32All64_DOF3;
typedef GMRESSolver<int, double, double, double, 4> GMRESSolver_I32All64_DOF4;

typedef GMRESSolver<int, float , double, double, 1> GMRESSolver_I32K64P64D32_DOF1;
typedef GMRESSolver<int, float , double, double, 2> GMRESSolver_I32K64P64D32_DOF2;
typedef GMRESSolver<int, float , double, double, 3> GMRESSolver_I32K64P64D32_DOF3;
typedef GMRESSolver<int, float , double, double, 4> GMRESSolver_I32K64P64D32_DOF4;

typedef GMRESSolver<int, float , float , double, 1> GMRESSolver_I32K64P32D32_DOF1;
typedef GMRESSolver<int, float , float , double, 2> GMRESSolver_I32K64P32D32_DOF2;
typedef GMRESSolver<int, float , float , double, 3> GMRESSolver_I32K64P32D32_DOF3;
typedef GMRESSolver<int, float , float , double, 4> GMRESSolver_I32K64P32D32_DOF4;

typedef GMRESSolver<int, float , float , float , 1> GMRESSolver_I32All32_DOF1;
typedef GMRESSolver<int, float , float , float , 2> GMRESSolver_I32All32_DOF2;
typedef GMRESSolver<int, float , float , float , 3> GMRESSolver_I32All32_DOF3;
typedef GMRESSolver<int, float , float , float , 4> GMRESSolver_I32All32_DOF4;
#ifdef USE_FP16
typedef GMRESSolver<int, __fp16, float , double, 1> GMRESSolver_I32K64P32D16_DOF1;
typedef GMRESSolver<int, __fp16, float , double, 2> GMRESSolver_I32K64P32D16_DOF2;
typedef GMRESSolver<int, __fp16, float , double, 3> GMRESSolver_I32K64P32D16_DOF3;
typedef GMRESSolver<int, __fp16, float , double, 4> GMRESSolver_I32K64P32D16_DOF4;

typedef GMRESSolver<int, __fp16, float , float , 1> GMRESSolver_I32K32P32D16_DOF1;
typedef GMRESSolver<int, __fp16, float , float , 2> GMRESSolver_I32K32P32D16_DOF2;
typedef GMRESSolver<int, __fp16, float , float , 3> GMRESSolver_I32K32P32D16_DOF3;
typedef GMRESSolver<int, __fp16, float , float , 4> GMRESSolver_I32K32P32D16_DOF4;
#endif

#endif